package com.hjh.thread.completablefuture.cf.cf;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;



/***
 * 演示异常通知的情况
 * @author joy lee
 *
 */
public class BaseComFutureExceptionally2 {

	public static void main(String[] args) throws InterruptedException {
		ExecutorService executor = Executors.newFixedThreadPool(5);
		/*
		 * 新建一个CompletableFuture对象
		 */
		CompletableFuture<String> resultCompletableFuture = CompletableFuture.supplyAsync(new Supplier<String>() {
			@Override
			public String get() {
				try {
					System.out.println("get start,will sleep 3s");
					TimeUnit.SECONDS.sleep(3);
					throw new RuntimeException("错误");
					//			System.out.println(Thread.currentThread().getName());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				return "Hello CompletableFuture";
			}
		}, executor);

		System.out.println(resultCompletableFuture.thenAccept(new Consumer<String>() {
			@Override
			public void accept(String t) {
				System.out.println("进入回调函数-" + t);
				throw new RuntimeException("aaaaa");
//				System.out.println(Thread.currentThread().getName());
			}

		}).exceptionally(new Function<Throwable, Void>() {

			@Override
			public Void apply(Throwable t) {
				System.out.println(t.getMessage());
				return null;
			}
		}));

		//resultCompletableFuture.completeExceptionally(new Exception("error"));

		System.out.println("it will shutdown 10's later");
		TimeUnit.SECONDS.sleep(10);

		executor.shutdown();

		System.out.println("time out ,main shutdown now");
	}

}
/**
 * 我们往往不仅需要通过回调的方式，让线程不阻塞
 * 我们还需要将这些回调操作串起来
 * 接着请看下面的转换
 * 需要用到apply函数组
 *
 *
 * public <U> CompletableFuture<U> 	thenApply(Function<? super T,? extends U> fn)
 * public <U> CompletableFuture<U> 	thenApplyAsync(Function<? super T,? extends U> fn)
 * public <U> CompletableFuture<U> 	thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
 * 当原来的CompletableFuture计算完后，
 * 将结果传递给函数fn，
 * 将fn的结果作为新的CompletableFuture的参数去参与运算。
 * 因此它的功能相当于将CompletableFuture<T>转换成CompletableFuture<U>
 *
 * 持续这么循环的调下去，有点像递归，当然，递归是本函数的持续调用（直到递归条件不满足）
 *
 *
 */
